namespace Loader
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.ComponentModel.Design;
    using System.ComponentModel.Design.Serialization;
    using System.Diagnostics;
    using System.Globalization;
    using System.IO;
    using System.Reflection;
    using System.Runtime.InteropServices;
    using System.Runtime.Serialization.Formatters.Binary;
    using System.Windows.Forms;
    using System.Xml;

    public class BasicHostLoader : BasicDesignerLoader
    {
        private bool bRun;
        private bool dirty;
        private string fileName;
        private IDesignerLoaderHost host;
        public List<IComponent> mComponents;
        private static readonly Attribute[] propertyAttributes = new Attribute[] { DesignOnlyAttribute.No };
        private IComponent root;
        private System.Type rootComponentType;
        private bool unsaved;
        private XmlDocument xmlDocument;

        public BasicHostLoader(System.Type rootComponentType)
        {
            this.dirty = true;
            this.bRun = false;
            this.mComponents = new List<IComponent>();
            this.rootComponentType = rootComponentType;
            this.Modified = true;
        }

        public BasicHostLoader(string fileName, bool bRun)
        {
            this.dirty = true;
            this.bRun = false;
            this.mComponents = new List<IComponent>();
            if (fileName == null)
            {
                throw new ArgumentNullException("fileName");
            }
            this.bRun = bRun;
            this.fileName = fileName;
        }

        public override void Dispose()
        {
            IComponentChangeService service = this.host.GetService(typeof(IComponentChangeService)) as IComponentChangeService;
            if (service != null)
            {
                service.ComponentChanged -= new ComponentChangedEventHandler(this.OnComponentChanged);
                service.ComponentAdded -= new ComponentEventHandler(this.OnComponentAddedRemoved);
                service.ComponentRemoved -= new ComponentEventHandler(this.OnComponentAddedRemoved);
            }
        }

        public string GetCode()
        {
            this.Flush();
            StringWriter w = new StringWriter();
            XmlTextWriter writer2 = new XmlTextWriter(w);
            writer2.Formatting = Formatting.Indented;
            this.xmlDocument.WriteTo(writer2);
            string str = w.ToString().Replace("<DOCUMENT_ELEMENT>", "").Replace("</DOCUMENT_ELEMENT>", "");
            w.Close();
            return str;
        }

        private bool GetConversionSupported(TypeConverter converter, System.Type conversionType)
        {
            return (converter.CanConvertFrom(conversionType) && converter.CanConvertTo(conversionType));
        }

        private string LoadFile(string fileName, ArrayList errors, out XmlDocument document)
        {
            string str = null;
            try
            {
                StreamReader reader = new StreamReader(fileName);
                string xml = reader.ReadToEnd();
                reader.Close();
                xml = "<DOCUMENT_ELEMENT>" + xml + "</DOCUMENT_ELEMENT>";
                XmlDocument document2 = new XmlDocument();
                document2.LoadXml(xml);
                foreach (XmlNode node in document2.DocumentElement.ChildNodes)
                {
                    if (str == null)
                    {
                        str = node.Attributes["name"].Value;
                    }
                    if (node.Name.Equals("Object"))
                    {
                        this.LoadObject(node, errors);
                    }
                    else
                    {
                        errors.Add(string.Format("Node type {0} is not allowed here.", node.Name));
                    }
                }
                document = document2;
            }
            catch (Exception exception)
            {
                document = null;
                errors.Add(exception);
            }
            return str;
        }

        private object LoadObject(XmlNode node, ArrayList errors)
        {
            object obj2;
            XmlAttribute attribute = node.Attributes["type"];
            if (attribute == null)
            {
                errors.Add("<Object> tag is missing required type attribute");
                return null;
            }
            System.Type c = System.Type.GetType(attribute.Value);
            if (c == null)
            {
                errors.Add(string.Format("Type {0} could not be loaded.", attribute.Value));
                return null;
            }
            XmlAttribute attribute2 = node.Attributes["name"];
            if (typeof(IComponent).IsAssignableFrom(c))
            {
                if (attribute2 == null)
                {
                    obj2 = this.host.CreateComponent(c);
                    this.mComponents.Add((IComponent) obj2);
                }
                else
                {
                    obj2 = this.host.CreateComponent(c, attribute2.Value);
                    this.mComponents.Add((IComponent) obj2);
                }
            }
            else
            {
                obj2 = Activator.CreateInstance(c);
                this.mComponents.Add((IComponent) obj2);
            }
            XmlAttribute attribute3 = node.Attributes["children"];
            IList list = null;
            if (attribute3 != null)
            {
                PropertyDescriptor descriptor = TypeDescriptor.GetProperties(obj2)[attribute3.Value];
                if (descriptor == null)
                {
                    errors.Add(string.Format("The children attribute lists {0} as the child collection but this is not a property on {1}", attribute3.Value, obj2.GetType().FullName));
                }
                else
                {
                    list = descriptor.GetValue(obj2) as IList;
                    if (list == null)
                    {
                        errors.Add(string.Format("The property {0} was found but did not return a valid IList", descriptor.Name));
                    }
                }
            }
            foreach (XmlNode node2 in node.ChildNodes)
            {
                if (node2.Name.Equals("Object"))
                {
                    if (attribute3 == null)
                    {
                        errors.Add("Child object found but there is no children attribute");
                        continue;
                    }
                    if (list != null)
                    {
                        object obj3 = this.LoadObject(node2, errors);
                        list.Add(obj3);
                    }
                }
                else if (node2.Name.Equals("Property"))
                {
                    this.ReadProperty(node2, obj2, errors);
                }
                else if (node2.Name.Equals("Event"))
                {
                    this.ReadEvent(node2, obj2, errors);
                }
            }
            return obj2;
        }

        private void OnComponentAddedRemoved(object sender, ComponentEventArgs ce)
        {
            this.dirty = true;
            this.unsaved = true;
        }

        private void OnComponentChanged(object sender, ComponentChangedEventArgs ce)
        {
            this.dirty = true;
            this.unsaved = true;
        }

        protected override void PerformFlush(IDesignerSerializationManager designerSerializationManager)
        {
            if (!this.dirty)
            {
            }
        }

        public void PerformFlushWorker()
        {
            XmlDocument document = new XmlDocument();
            document.AppendChild(document.CreateElement("DOCUMENT_ELEMENT"));
            IDesignerHost service = (IDesignerHost) this.host.GetService(typeof(IDesignerHost));
            this.root = service.RootComponent;
            Hashtable nametable = new Hashtable(service.Container.Components.Count);
            IDesignerSerializationManager manager = this.host.GetService(typeof(IDesignerSerializationManager)) as IDesignerSerializationManager;
            document.DocumentElement.AppendChild(this.WriteObject(document, nametable, this.root));
            foreach (IComponent component in service.Container.Components)
            {
                if (!((component == this.root) || nametable.ContainsKey(component)))
                {
                    document.DocumentElement.AppendChild(this.WriteObject(document, nametable, component));
                }
            }
            this.xmlDocument = document;
        }

        protected override void PerformLoad(IDesignerSerializationManager designerSerializationManager)
        {
            this.host = base.LoaderHost;
            if (this.host == null)
            {
                throw new ArgumentNullException("BasicHostLoader.BeginLoad: Invalid designerLoaderHost.");
            }
            ArrayList errors = new ArrayList();
            bool successful = true;
            string baseClassName = "";
            if (!this.bRun)
            {
                if (this.fileName == null)
                {
                    if (this.rootComponentType != typeof(Form))
                    {
                        if (this.rootComponentType != typeof(UserControl))
                        {
                            if (this.rootComponentType != typeof(Component))
                            {
                                throw new Exception("Undefined Host Type: " + this.rootComponentType.ToString());
                            }
                            this.host.CreateComponent(typeof(Component));
                            baseClassName = "Component1";
                        }
                        else
                        {
                            this.host.CreateComponent(typeof(UserControl));
                            baseClassName = "UserControl1";
                        }
                    }
                    else
                    {
                        this.host.CreateComponent(typeof(Form));
                        baseClassName = "Form1";
                    }
                }
                else
                {
                    baseClassName = this.ReadFile(this.fileName, errors, out this.xmlDocument);
                }
                IComponentChangeService service = this.host.GetService(typeof(IComponentChangeService)) as IComponentChangeService;
                if (service != null)
                {
                    service.ComponentChanged += new ComponentChangedEventHandler(this.OnComponentChanged);
                    service.ComponentAdded += new ComponentEventHandler(this.OnComponentAddedRemoved);
                    service.ComponentRemoved += new ComponentEventHandler(this.OnComponentAddedRemoved);
                }
                this.host.EndLoad(baseClassName, successful, errors);
                this.dirty = true;
                this.unsaved = false;
            }
            else
            {
                if (this.fileName != null)
                {
                    baseClassName = this.LoadFile(this.fileName, errors, out this.xmlDocument);
                }
                this.host.EndLoad(baseClassName, successful, errors);
            }
        }

        internal bool PromptDispose()
        {
            if (this.dirty || this.unsaved)
            {
                switch (MessageBox.Show("Save changes to existing designer?", "Unsaved Changes", MessageBoxButtons.YesNoCancel))
                {
                    case DialogResult.Cancel:
                        return false;

                    case DialogResult.Yes:
                        this.Save(false);
                        break;
                }
            }
            return true;
        }

        private void ReadEvent(XmlNode childNode, object instance, ArrayList errors)
        {
            IEventBindingService service = this.host.GetService(typeof(IEventBindingService)) as IEventBindingService;
            if (service == null)
            {
                errors.Add("Unable to contact event binding service so we can't bind any events");
            }
            else
            {
                XmlAttribute attribute = childNode.Attributes["name"];
                if (attribute == null)
                {
                    errors.Add("No event name");
                }
                else
                {
                    XmlAttribute attribute2 = childNode.Attributes["method"];
                    if (((attribute2 == null) || (attribute2.Value == null)) || (attribute2.Value.Length == 0))
                    {
                        errors.Add(string.Format("Event {0} has no method bound to it", new object[0]));
                    }
                    else
                    {
                        EventDescriptor e = TypeDescriptor.GetEvents(instance)[attribute.Value];
                        if (e == null)
                        {
                            errors.Add(string.Format("Event {0} does not exist on {1}", attribute.Value, instance.GetType().FullName));
                        }
                        else
                        {
                            PropertyDescriptor eventProperty = service.GetEventProperty(e);
                            Debug.Assert(eventProperty != null, "Bad event binding service");
                            try
                            {
                                eventProperty.SetValue(instance, attribute2.Value);
                            }
                            catch (Exception exception)
                            {
                                errors.Add(exception.Message);
                            }
                        }
                    }
                }
            }
        }

        private string ReadFile(string fileName, ArrayList errors, out XmlDocument document)
        {
            string str = null;
            try
            {
                StreamReader reader = new StreamReader(fileName);
                string xml = reader.ReadToEnd();
                reader.Close();
                xml = "<DOCUMENT_ELEMENT>" + xml + "</DOCUMENT_ELEMENT>";
                XmlDocument document2 = new XmlDocument();
                document2.LoadXml(xml);
                foreach (XmlNode node in document2.DocumentElement.ChildNodes)
                {
                    if (str == null)
                    {
                        str = node.Attributes["name"].Value;
                    }
                    if (node.Name.Equals("Object"))
                    {
                        this.ReadObject(node, errors);
                    }
                    else
                    {
                        errors.Add(string.Format("Node type {0} is not allowed here.", node.Name));
                    }
                }
                document = document2;
            }
            catch (Exception exception)
            {
                document = null;
                errors.Add(exception);
            }
            return str;
        }

        private object ReadInstanceDescriptor(XmlNode node, ArrayList errors)
        {
            XmlAttribute attribute = node.Attributes["member"];
            if (attribute == null)
            {
                errors.Add("No member attribute on instance descriptor");
                return null;
            }
            byte[] buffer = Convert.FromBase64String(attribute.Value);
            BinaryFormatter formatter = new BinaryFormatter();
            MemoryStream serializationStream = new MemoryStream(buffer);
            MemberInfo member = (MemberInfo) formatter.Deserialize(serializationStream);
            object[] arguments = null;
            if (member is MethodBase)
            {
                ParameterInfo[] parameters = ((MethodBase) member).GetParameters();
                arguments = new object[parameters.Length];
                int index = 0;
                foreach (XmlNode node2 in node.ChildNodes)
                {
                    if (node2.Name.Equals("Argument"))
                    {
                        object obj2;
                        if (!this.ReadValue(node2, TypeDescriptor.GetConverter(parameters[index].ParameterType), errors, out obj2))
                        {
                            return null;
                        }
                        arguments[index++] = obj2;
                    }
                }
                if (index != parameters.Length)
                {
                    errors.Add(string.Format("Member {0} requires {1} arguments, not {2}.", member.Name, arguments.Length, index));
                    return null;
                }
            }
            object instance = new InstanceDescriptor(member, arguments).Invoke();
            foreach (XmlNode node3 in node.ChildNodes)
            {
                if (node3.Name.Equals("Property"))
                {
                    this.ReadProperty(node3, instance, errors);
                }
            }
            return instance;
        }

        private object ReadObject(XmlNode node, ArrayList errors)
        {
            object obj2;
            XmlAttribute attribute = node.Attributes["type"];
            if (attribute == null)
            {
                errors.Add("<Object> tag is missing required type attribute");
                return null;
            }
            System.Type c = System.Type.GetType(attribute.Value);
            if (c == null)
            {
                errors.Add(string.Format("Type {0} could not be loaded.", attribute.Value));
                return null;
            }
            XmlAttribute attribute2 = node.Attributes["name"];
            if (typeof(IComponent).IsAssignableFrom(c))
            {
                if (attribute2 == null)
                {
                    obj2 = this.host.CreateComponent(c);
                }
                else
                {
                    obj2 = this.host.CreateComponent(c, attribute2.Value);
                }
            }
            else
            {
                obj2 = Activator.CreateInstance(c);
            }
            XmlAttribute attribute3 = node.Attributes["children"];
            IList list = null;
            if (attribute3 != null)
            {
                PropertyDescriptor descriptor = TypeDescriptor.GetProperties(obj2)[attribute3.Value];
                if (descriptor == null)
                {
                    errors.Add(string.Format("The children attribute lists {0} as the child collection but this is not a property on {1}", attribute3.Value, obj2.GetType().FullName));
                }
                else
                {
                    list = descriptor.GetValue(obj2) as IList;
                    if (list == null)
                    {
                        errors.Add(string.Format("The property {0} was found but did not return a valid IList", descriptor.Name));
                    }
                }
            }
            foreach (XmlNode node2 in node.ChildNodes)
            {
                if (node2.Name.Equals("Object"))
                {
                    if (attribute3 == null)
                    {
                        errors.Add("Child object found but there is no children attribute");
                        continue;
                    }
                    if (list != null)
                    {
                        object obj3 = this.ReadObject(node2, errors);
                        list.Add(obj3);
                    }
                }
                else if (node2.Name.Equals("Property"))
                {
                    this.ReadProperty(node2, obj2, errors);
                }
                else if (node2.Name.Equals("Event"))
                {
                    this.ReadEvent(node2, obj2, errors);
                }
            }
            return obj2;
        }

        private void ReadProperty(XmlNode node, object instance, ArrayList errors)
        {
            XmlAttribute attribute = node.Attributes["name"];
            if (attribute == null)
            {
                errors.Add("Property has no name");
            }
            else
            {
                PropertyDescriptor descriptor = TypeDescriptor.GetProperties(instance)[attribute.Value];
                if (descriptor == null)
                {
                    errors.Add(string.Format("Property {0} does not exist on {1}", attribute.Value, instance.GetType().FullName));
                }
                else
                {
                    object obj2;
                    Exception exception;
                    if (descriptor.Attributes.Contains(DesignerSerializationVisibilityAttribute.Content))
                    {
                        obj2 = descriptor.GetValue(instance);
                        if (obj2 is IList)
                        {
                            foreach (XmlNode node2 in node.ChildNodes)
                            {
                                if (node2.Name.Equals("Item"))
                                {
                                    XmlAttribute attribute2 = node2.Attributes["type"];
                                    if (attribute2 == null)
                                    {
                                        errors.Add("Item has no type attribute");
                                    }
                                    else
                                    {
                                        Type type = Type.GetType(attribute2.Value);
                                        if (type == null)
                                        {
                                            errors.Add(string.Format("Item type {0} could not be found.", attribute2.Value));
                                        }
                                        else
                                        {
                                            object obj3;
                                            if (this.ReadValue(node2, TypeDescriptor.GetConverter(type), errors, out obj3))
                                            {
                                                try
                                                {
                                                    ((IList)obj2).Add(obj3);
                                                }
                                                catch (Exception exception1)
                                                {
                                                    exception = exception1;
                                                    errors.Add(exception.Message);
                                                }
                                            }
                                        }
                                    }
                                }
                                else
                                {
                                    errors.Add(string.Format("Only Item elements are allowed in collections, not {0} elements.", node2.Name));
                                }
                            }
                        }
                        else
                        {
                            foreach (XmlNode node2 in node.ChildNodes)
                            {
                                if (node2.Name.Equals("Property"))
                                {
                                    this.ReadProperty(node2, obj2, errors);
                                }
                                else
                                {
                                    errors.Add(string.Format("Only Property elements are allowed in content properties, not {0} elements.", node2.Name));
                                }
                            }
                        }
                    }
                    else if (this.ReadValue(node, descriptor.Converter, errors, out obj2))
                    {
                        try
                        {
                            descriptor.SetValue(instance, obj2);
                        }
                        catch (Exception exception2)
                        {
                            exception = exception2;
                            errors.Add(exception.Message);
                        }
                    }
                }
            }
        }
        private bool ReadValue(XmlNode node, TypeConverter converter, ArrayList errors, out object value)
        {
            try
            {
                foreach (XmlNode node2 in node.ChildNodes)
                {
                    if (node2.NodeType == XmlNodeType.Text)
                    {
                        value = converter.ConvertFromInvariantString(node.InnerText);
                        return true;
                    }
                    if (node2.Name.Equals("Binary"))
                    {
                        byte[] buffer = Convert.FromBase64String(node2.InnerText);
                        if (this.GetConversionSupported(converter, typeof(byte[])))
                        {
                            value = converter.ConvertFrom(null, CultureInfo.InvariantCulture, buffer);
                            return true;
                        }
                        BinaryFormatter formatter = new BinaryFormatter();
                        MemoryStream serializationStream = new MemoryStream(buffer);
                        value = formatter.Deserialize(serializationStream);
                        return true;
                    }
                    if (node2.Name.Equals("InstanceDescriptor"))
                    {
                        value = this.ReadInstanceDescriptor(node2, errors);
                        return (value != null);
                    }
                    errors.Add(string.Format("Unexpected element type {0}", node2.Name));
                    value = null;
                    return false;
                }
                value = null;
                return true;
            }
            catch (Exception exception)
            {
                errors.Add(exception.Message);
                value = null;
                return false;
            }
        }

        public void Save()
        {
            this.Save(false);
        }

        public void Save(bool forceFilePrompt)
        {
            try
            {
                this.Flush();
                int filterIndex = 3;
                if ((this.fileName == null) || forceFilePrompt)
                {
                    SaveFileDialog dialog = new SaveFileDialog();
                    dialog.DefaultExt = "xml";
                    dialog.Filter = "XML Files|*.xml";
                    if (dialog.ShowDialog() == DialogResult.OK)
                    {
                        this.fileName = dialog.FileName;
                        filterIndex = dialog.FilterIndex;
                    }
                }
                if (this.fileName != null)
                {
                    switch (filterIndex)
                    {
                        case 1:
                        {
                            StringWriter w = new StringWriter();
                            XmlTextWriter writer2 = new XmlTextWriter(w);
                            writer2.Formatting = Formatting.Indented;
                            this.xmlDocument.WriteTo(writer2);
                            string str = w.ToString().Replace("<DOCUMENT_ELEMENT>", "").Replace("</DOCUMENT_ELEMENT>", "");
                            writer2.Close();
                            StreamWriter writer3 = new StreamWriter(this.fileName);
                            writer3.Write(str);
                            writer3.Close();
                        }
                        break;
                    }
                    this.unsaved = false;
                }
            }
            catch (Exception exception)
            {
                MessageBox.Show("存储过程中出现错误: " + exception.ToString());
            }
        }

        public void Save(string spath)
        {
            try
            {
                this.PerformFlushWorker();
                if (spath != "")
                {
                    StringWriter w = new StringWriter();
                    XmlTextWriter writer2 = new XmlTextWriter(w);
                    writer2.Formatting = Formatting.Indented;
                    this.xmlDocument.WriteTo(writer2);
                    string str = w.ToString().Replace("<DOCUMENT_ELEMENT>", "").Replace("</DOCUMENT_ELEMENT>", "");
                    writer2.Close();
                    StreamWriter writer3 = new StreamWriter(spath);
                    writer3.Write(str);
                    writer3.Close();
                    this.unsaved = false;
                }
            }
            catch (Exception exception)
            {
                MessageBox.Show("存储过程中出现错误: " + exception.ToString());
            }
        }

        private XmlNode WriteBinary(XmlDocument document, byte[] value)
        {
            XmlNode node = document.CreateElement("Binary");
            node.InnerText = Convert.ToBase64String(value);
            return node;
        }

        private void WriteCollection(XmlDocument document, IList list, XmlNode parent)
        {
            foreach (object obj2 in list)
            {
                XmlNode node = document.CreateElement("Item");
                XmlAttribute attribute = document.CreateAttribute("type");
                attribute.Value = obj2.GetType().AssemblyQualifiedName;
                node.Attributes.Append(attribute);
                this.WriteValue(document, obj2, node);
                parent.AppendChild(node);
            }
        }

        private XmlNode WriteInstanceDescriptor(XmlDocument document, InstanceDescriptor desc, object value)
        {
            XmlNode parent = document.CreateElement("InstanceDescriptor");
            BinaryFormatter formatter = new BinaryFormatter();
            MemoryStream serializationStream = new MemoryStream();
            formatter.Serialize(serializationStream, desc.MemberInfo);
            XmlAttribute node = document.CreateAttribute("member");
            node.Value = Convert.ToBase64String(serializationStream.ToArray());
            parent.Attributes.Append(node);
            foreach (object obj2 in desc.Arguments)
            {
                XmlNode node2 = document.CreateElement("Argument");
                if (this.WriteValue(document, obj2, node2))
                {
                    parent.AppendChild(node2);
                }
            }
            if (!desc.IsComplete)
            {
                PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(value, propertyAttributes);
                this.WriteProperties(document, properties, value, parent, "Property");
            }
            return parent;
        }

        private XmlNode WriteObject(XmlDocument document, IDictionary nametable, object value)
        {
            IDesignerHost host = (IDesignerHost) this.host.GetService(typeof(IDesignerHost));
            Debug.Assert(value != null, "Should not invoke WriteObject with a null value");
            XmlNode parent = document.CreateElement("Object");
            XmlAttribute node = document.CreateAttribute("type");
            node.Value = value.GetType().AssemblyQualifiedName;
            parent.Attributes.Append(node);
            IComponent component = value as IComponent;
            if (((component != null) && (component.Site != null)) && (component.Site.Name != null))
            {
                XmlAttribute attribute2 = document.CreateAttribute("name");
                attribute2.Value = component.Site.Name;
                parent.Attributes.Append(attribute2);
                Debug.Assert(nametable[component] == null, "WriteObject should not be called more than once for the same object.  Use WriteReference instead");
                nametable[value] = component.Site.Name;
            }
            bool flag = value is Control;
            if (flag)
            {
                XmlAttribute attribute3 = document.CreateAttribute("children");
                attribute3.Value = "Controls";
                parent.Attributes.Append(attribute3);
            }
            if (component != null)
            {
                if (flag)
                {
                    foreach (Control control in ((Control) value).Controls)
                    {
                        if ((control.Site != null) && (control.Site.Container == host.Container))
                        {
                            parent.AppendChild(this.WriteObject(document, nametable, control));
                        }
                    }
                }
                PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(value, propertyAttributes);
                if (flag)
                {
                    PropertyDescriptor descriptor = properties["Controls"];
                    if (descriptor != null)
                    {
                        PropertyDescriptor[] descriptorArray = new PropertyDescriptor[properties.Count - 1];
                        int num = 0;
                        foreach (PropertyDescriptor descriptor2 in properties)
                        {
                            if (descriptor2 != descriptor)
                            {
                                descriptorArray[num++] = descriptor2;
                            }
                        }
                        properties = new PropertyDescriptorCollection(descriptorArray);
                    }
                }
                this.WriteProperties(document, properties, value, parent, "Property");
                EventDescriptorCollection events = TypeDescriptor.GetEvents(value, propertyAttributes);
                IEventBindingService service = this.host.GetService(typeof(IEventBindingService)) as IEventBindingService;
                if (service != null)
                {
                    properties = service.GetEventProperties(events);
                    this.WriteProperties(document, properties, value, parent, "Event");
                }
                return parent;
            }
            this.WriteValue(document, value, parent);
            return parent;
        }

        private void WriteProperties(XmlDocument document, PropertyDescriptorCollection properties, object value, XmlNode parent, string elementName)
        {
            foreach (PropertyDescriptor descriptor in properties)
            {
                XmlNode node;
                object obj2;
                PropertyDescriptorCollection descriptors;
                if (descriptor.Name == "AutoScaleBaseSize")
                {
                    string name = descriptor.Name;
                }
                if (descriptor.ShouldSerializeValue(value))
                {
                    string str2 = parent.Name;
                    node = document.CreateElement(elementName);
                    XmlAttribute attribute = document.CreateAttribute("name");
                    attribute.Value = descriptor.Name;
                    node.Attributes.Append(attribute);
                    DesignerSerializationVisibilityAttribute attribute2 = (DesignerSerializationVisibilityAttribute) descriptor.Attributes[typeof(DesignerSerializationVisibilityAttribute)];
                    switch (attribute2.Visibility)
                    {
                        case DesignerSerializationVisibility.Visible:
                            if (!(descriptor.IsReadOnly || !this.WriteValue(document, descriptor.GetValue(value), node)))
                            {
                                parent.AppendChild(node);
                            }
                            break;

                        case DesignerSerializationVisibility.Content:
                            obj2 = descriptor.GetValue(value);
                            if (!typeof(IList).IsAssignableFrom(descriptor.PropertyType))
                            {
                                descriptors = TypeDescriptor.GetProperties(obj2, propertyAttributes);
                                this.WriteProperties(document, descriptors, obj2, node, elementName);
                                if (node.ChildNodes.Count > 0)
                                {
                                    parent.AppendChild(node);
                                }
                                break;
                            }
                            this.WriteCollection(document, (IList) obj2, node);
                            if (node.ChildNodes.Count > 0)
                            {
                                parent.AppendChild(node);
                            }
                            break;
                    }
                }
            }
        }

        private XmlNode WriteReference(XmlDocument document, IComponent value)
        {
            IDesignerHost service = (IDesignerHost) this.host.GetService(typeof(IDesignerHost));
            Debug.Assert(((value != null) && (value.Site != null)) && (value.Site.Container == service.Container), "Invalid component passed to WriteReference");
            XmlNode node = document.CreateElement("Reference");
            XmlAttribute attribute = document.CreateAttribute("name");
            attribute.Value = value.Site.Name;
            node.Attributes.Append(attribute);
            return node;
        }

        private bool WriteValue(XmlDocument document, object value, XmlNode parent)
        {
            IDesignerHost service = (IDesignerHost) this.host.GetService(typeof(IDesignerHost));
            if (value != null)
            {
                TypeConverter converter = TypeDescriptor.GetConverter(value);
                if (this.GetConversionSupported(converter, typeof(string)))
                {
                    parent.InnerText = (string) converter.ConvertTo(null, CultureInfo.InvariantCulture, value, typeof(string));
                }
                else if (this.GetConversionSupported(converter, typeof(byte[])))
                {
                    byte[] buffer = (byte[]) converter.ConvertTo(null, CultureInfo.InvariantCulture, value, typeof(byte[]));
                    parent.AppendChild(this.WriteBinary(document, buffer));
                }
                else if (this.GetConversionSupported(converter, typeof(InstanceDescriptor)))
                {
                    InstanceDescriptor desc = (InstanceDescriptor) converter.ConvertTo(null, CultureInfo.InvariantCulture, value, typeof(InstanceDescriptor));
                    parent.AppendChild(this.WriteInstanceDescriptor(document, desc, value));
                }
                else if (((value is IComponent) && (((IComponent) value).Site != null)) && (((IComponent) value).Site.Container == service.Container))
                {
                    parent.AppendChild(this.WriteReference(document, (IComponent) value));
                }
                else if (value.GetType().IsSerializable)
                {
                    BinaryFormatter formatter = new BinaryFormatter();
                    MemoryStream serializationStream = new MemoryStream();
                    formatter.Serialize(serializationStream, value);
                    XmlNode newChild = this.WriteBinary(document, serializationStream.ToArray());
                    parent.AppendChild(newChild);
                }
                else
                {
                    return false;
                }
            }
            return true;
        }
    }
}

